	
tdDropDownDB = {}

local profiles = {}
local events = {}
local L = tdDropDown_Locale
local O = tdDropDown_Option

O.MAX = O.MAX and tonumber(O.MAX) or 40

local function IsInList(list, text)
	for key, value in ipairs(list) do
		if value == text then
			return key
		end
	end
end

local function ToSortString(text)
	return format("%10d%s", string.len(text), text)
end

local function tdDropDown_HeaderClick()
	local pos = IsInList(tdDropDownDB[this.owner.profile], this.value)
	if pos then
		tremove(tdDropDownDB[this.owner.profile], pos)
		this.owner.editbox:SetText("")
	else
		tinsert(tdDropDownDB[this.owner.profile], this.value)
	end
	sort(tdDropDownDB[this.owner.profile], function(a, b)
		return ToSortString(a) < ToSortString(b)
	end)
end

local function tdDropDown_ButtonClick()
	this.owner.editbox:SetText(this.value)
	if this.owner.click then
		this.owner.click()
	end
end

local function tdDropDown_Initialize(dropdown, level)
	level = level or 1

	local list = tdDropDownDB[dropdown.profile]
	local text = dropdown.editbox:GetText()
	local info = {}

	if not text or text == "" or text == SEARCH then text = nil end

	if text and level == 1 then
		local str = IsInList(list, text) and L.Del or L.Add

		info = { owner = dropdown, notCheckable = 1,}
		info.text = format(str, text)
		info.value = text;
		info.func = tdDropDown_HeaderClick
		UIDropDownMenu_AddButton(info, 1)

		if #(list) > 0 then
			info.isTitle = 1
			info.text = ""
			info.value = ""
			info.func = nil
			UIDropDownMenu_AddButton(info, 1)
		end
	end

	info = { owner = dropdown, func = tdDropDown_ButtonClick,}

	local start  = (level - 1) * O.MAX + 1
	for i = start, start + O.MAX - 1 do
		if not list[i] then
			break
		end
		info.text = list[i]
		info.value = list[i];
		UIDropDownMenu_AddButton(info, level)
	end

	if #(list) > start + O.MAX - 1 then
		info.notCheckable = 1
		info.text = L.Next
		info.value = nil
		info.func = nil
		info.hasArrow = true
		UIDropDownMenu_AddButton(info, level)
	end
end

local function OnClick()
	if arg1 == "LeftButton" then
		ToggleDropDownMenu(1, nil, this.dropdown, this, - this.dropdown.editbox:GetWidth() , 5)
	else
		this.dropdown.editbox:SetText("")
	end
end
local function OnEnter()
	GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
	GameTooltip:SetText(format(L.Num, #(tdDropDownDB[this.dropdown.profile])), 1, 1, 1)
	GameTooltip:AddLine(L.ShowList)
	GameTooltip:AddLine(L.ClearInput)
	GameTooltip:Show()
end

local function OnLeave()
	GameTooltip:Hide()
end

local function CreateDropDown(profile, short, move, click)
	if not profile then return end

	local editbox = getglobal(profile)
	if not editbox then return end

	tdDropDownDB[profile] = tdDropDownDB[profile] or {}

	local name = editbox:GetName()
	local dropdown = CreateFrame("Frame", name.."Dropdown", editbox, "UIDropDownMenuTemplate")
	--dropdown.point = "TOPLEFT"
	--dropdown.relativeTo = "TOPLEFT"

	if short then
		editbox:SetWidth(editbox:GetWidth() - 19)
	end
	if move then
		local point, relative, rpoint, x, y = editbox:GetPoint()
		if string.find(point, "RIGHT") then
			editbox:ClearAllPoints()
			editbox:SetPoint(point, relative, rpoint, x - 19, y)
		elseif point == "CENTER" then
			editbox:ClearAllPoints()
			editbox:SetPoint(point, relative, rpoint, x - 19, y)
		end
	end

	local button = CreateFrame("Button", name.."Button", editbox)
	button:SetWidth(24);button:SetHeight(24)
	button:SetNormalTexture("Interface/ChatFrame/UI-ChatIcon-ScrollDown-Up")
	button:SetPushedTexture("Interface/ChatFrame/UI-ChatIcon-ScrollDown-Down")
	button:SetHighlightTexture("Interface/Buttons/UI-Common-MouseHilight")
	button:SetPoint("LEFT", editbox, "RIGHT", -5, 0)
	button:RegisterForClicks("LeftButtonUp", "RightButtonUp")

	button.dropdown = dropdown
	dropdown.editbox = editbox
	dropdown.profile = profile
	dropdown.click = click

	button:SetScript("OnClick", OnClick)
	button:SetScript("OnEnter", OnEnter)
	button:SetScript("OnLeave", OnLeave)

	UIDropDownMenu_Initialize(dropdown, tdDropDown_Initialize, O.Menu and "MENU" or nil);
end

local f = CreateFrame("Frame")
f:SetScript("OnEvent", function(self, event, ...)
	if profiles[event] then
		for key, value in ipairs(profiles[event]) do
			if value.func(...) then
				CreateDropDown(value.profile, value.short, value.move, value.click)
				tremove(profiles[event], key)
			end
		end
		if #(profiles[event]) <= 0 then
			self:UnregisterEvent(event)
			events[event] = nil
		end
	end
end)

function tdCreateDropDown(table)
	if not table or not table.profile then return end

	local event = table.event or "VARIABLES_LOADED"
	local func = table.func or function() return true end

	profiles[event] = profiles[event] or {}
	tinsert(profiles[event], {
		profile = table.profile,
		func = func,
		short = table.short,
		move = table.move,
		click = table.click
	})
	if not events[event] then
		f:RegisterEvent(event)
		events[event] = true
	end
end
